//==============================================================================
#include "Button.h"

using namespace ui;

//==============================================================================
Button::Button(int posX, int posY, int width, int height, COMPONENT_TYPE type, string name) : Component(posX, posY, width, height, type, name)
{
	setPressSurf(NULL);
	setUnPressSurf(NULL);
	setPressed(false);
}
//------------------------------------------------------------------------------
Button::Button(int posX, int posY, COMPONENT_TYPE type) : Component(posX, posY, 120, 40, type, "Button")
{
	setPressSurf(NULL);
	setUnPressSurf(NULL);
	setPressed(false);
}
//------------------------------------------------------------------------------
Button::~Button(void)
{
	//Se liberan las superficies cargadas del botón
	SDL_FreeSurface(getPressSurf());
	SDL_FreeSurface(getUnPressSurf());
	setPressSurf(NULL);
	setUnPressSurf(NULL);
	setPressed(false);
}
//------------------------------------------------------------------------------
void  Button::setPressed(bool flag)
{
	this->pressed = flag;
}
//------------------------------------------------------------------------------
bool  Button::getPressed()
{
	return this->pressed;
}
//------------------------------------------------------------------------------
void  Button::setPressSurf(SDL_Surface* surface)
{
	this->pressSurf = surface;
}
//------------------------------------------------------------------------------
SDL_Surface*  Button::getPressSurf()
{
	return this->pressSurf;
}
//------------------------------------------------------------------------------
void  Button::setUnPressSurf(SDL_Surface* surface)
{
	this->unPressSurf = surface;
}
//------------------------------------------------------------------------------
SDL_Surface*  Button::getUnPressSurf()
{
	return this->unPressSurf;
}
//------------------------------------------------------------------------------
void Button::loadSurface() throw (SDL_Exception)
{
	string path_ButtonUnPressed = BUTTON_PATH;
	string path_ButtonPressed = BUTTON_PATH;
	//Depediendo del tipo de botón elegido por parámetro se setean los paths de las imagenes correspondientes
    switch (getType())
    {
		case SERVER_BUTTON:
		{
			path_ButtonPressed.append("btn_server_press.png");
			path_ButtonUnPressed.append("btn_server.png");
        }break;

        case PLAYER_BUTTON:
		{
			path_ButtonPressed.append("btn_player_press.png");
			path_ButtonUnPressed.append("btn_player.png");
        }break;

        case SPECTATOR_BUTTON:
		{
            path_ButtonPressed.append("btn_spectator_press.png");
			path_ButtonUnPressed.append("btn_spectator.png");
        }break;

		case ENTER_BUTTON:
		{
			path_ButtonPressed.append("btn_enter_press.png");
			path_ButtonUnPressed.append("btn_enter.png");
        }break;

        case OPEN_BUTTON:
		{
			path_ButtonPressed.append("btn_open_press.png");
			path_ButtonUnPressed.append("btn_open.png");
        }break;

        case CLOSE_BUTTON:
		{
            path_ButtonPressed.append("btn_close_press.png");
			path_ButtonUnPressed.append("btn_close.png");
        }break;

        case CREATE_BUTTON:
		{
            path_ButtonPressed.append("btn_create_press.png");
			path_ButtonUnPressed.append("btn_create.png");
        }break;

        case REMOVE_BUTTON:
		{
            path_ButtonPressed.append("btn_remove_press.png");
			path_ButtonUnPressed.append("btn_remove.png");
        }break;

        case SAVE_BUTTON:
		{
            path_ButtonPressed.append("btn_save_press.png");
			path_ButtonUnPressed.append("btn_save.png");
        }break;

        case UPDATE_BUTTON:
		{
            path_ButtonPressed.append("btn_update_press.png");
			path_ButtonUnPressed.append("btn_update.png");
        }break;

		case ACCEPT_BUTTON:
		{
            path_ButtonPressed.append("btn_accept_press.png");
			path_ButtonUnPressed.append("btn_accept.png");
        }break;

        case CANCEL_BUTTON:
		{
            path_ButtonPressed.append("btn_cancel_press.png");
			path_ButtonUnPressed.append("btn_cancel.png");
        }break;

        case QUIT_BUTTON:
		{
            path_ButtonPressed.append("btn_quit_press.png");
			path_ButtonUnPressed.append("btn_quit.png");
        }break;

        case SCROLL_UP:
		{
            setHeight(13);
			setWidth(30);
            path_ButtonPressed.append("btn_scroll_up_press.png");
			path_ButtonUnPressed.append("btn_scroll_up.png");
        }break;

        case SCROLL_DOWN:
		{
            setHeight(13);
			setWidth(30);
            path_ButtonPressed.append("btn_scroll_down_press.png");
			path_ButtonUnPressed.append("btn_scroll_down.png");
        }break;

        default:
		{
			path_ButtonPressed.clear();
			path_ButtonUnPressed.clear();
            this->type = NONE;
        }break;
    }
	//Carga de las superficies del botón de acuerdo a la ruta recibida por parámetro
	SDL_Surface* surface = IMG_Load(path_ButtonPressed.c_str());
	setPressSurf(SDL_DisplayFormatAlpha(surface));
	SDL_FreeSurface(surface);
	surface = IMG_Load(path_ButtonUnPressed.c_str());
	setUnPressSurf(SDL_DisplayFormatAlpha(surface));
	SDL_FreeSurface(surface);
	if( (getPressSurf() == NULL) ||	(getUnPressSurf() == NULL) )
	{
	    std::string errorMessage ("BUTTON - LOAD SURFACE - ERROR");
	    throw(SDL_Exception(errorMessage));
	}
}
//------------------------------------------------------------------------------
COMPONENT_TYPE Button::handleEvent(SDL_Event* event)
{
	COMPONENT_TYPE type = NONE;

	//Si se presionó el boton izquierdo del mouse y el evento ocurrio dentro del área del componente se cambia el flag de presionado a verdadero
	if(event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT)
	{
        if(ocurredInside(event->button.x, event->button.y))
        {
            setPressed(true);
        }
	}
	else
	{
		//Si se soltó el botón izquierdo del mouse y el evento ocurrió dentro del área del componente el flag de presionado pasa a falso
		//Luego se seteará el tipo del botón al que le corresponde para ser devuelto, lo que derivará a una acción a realizar por el utilitario
		if( (event->type == SDL_MOUSEBUTTONUP) && (event->button.button == SDL_BUTTON_LEFT)
                && (getPressed()) && (ocurredInside(event->button.x, event->button.y)) )
        {
            setPressed(false);
			type = getType();
        }
		else
		{
			//Si el mouse se ha movido fuera del área del componente y el mismo se encontraba presionado, entonces es liberado
			if(event->type == SDL_MOUSEMOTION && this->pressed == true && !ocurredInside(event->motion.x, event->motion.y))
            {
				setPressed(false);
            }
		}
	}
	return type;
}
//------------------------------------------------------------------------------
void Button::draw(SDL_Surface* screen) throw (SDL_Exception)
{
    SDL_Rect button_rect;

	button_rect.x = getXCoordinate();
	button_rect.y = getYCoordinate();

	SDL_Surface* button_surface;

	if(this->pressed)
	{
		button_surface = getPressSurf();
	}

	else
	{
		button_surface = getUnPressSurf();
	}

	//Se dibuja la imagen superficial del boton
	if(SDL_BlitSurface(button_surface, NULL, screen, &button_rect))
	{
        std::string errorMessage ("BUTTON - BLIT SURFACE - ERROR");
	    throw SDL_Exception(errorMessage);
    }
}
//==============================================================================
